package org.redmagic.utils;

import java.util.Properties;

public class PlaceholderHelper {

    private final String placeholderPrefix;
    private final String placeholderSuffix;
    
    public PlaceholderHelper() {
        this("${", "}");
    }
    
    public PlaceholderHelper(String prefix, String suffix) {
        this.placeholderPrefix = prefix;
        this.placeholderSuffix = suffix;
    }
    
    public String resolve(String string, Properties properties) {
        int placeholderStartIndex = findPlaceholderStartIndex(string);
        if (placeholderStartIndex != -1) {
            if (isNested(string, placeholderStartIndex)) {
                throw new RuntimeException("Cannot handle nested placeholders.");
            } else {
                int placeholderEndIndex = findPlaceholderEndIndex(string, placeholderStartIndex);
                if (placeholderEndIndex != -1) {
                    String placeholder = string.substring(placeholderStartIndex, placeholderEndIndex);
                    String value = properties.getProperty(placeholder);
                    if (value != null) {
                        string = replace(string, placeholderStartIndex, placeholderEndIndex, value);
                        return resolve(string, properties);
                    } else {
                        throw new RuntimeException("Unable to resolve placeholder: " + placeholder);
                    }
                } else {
                    throw new RuntimeException("Expecting '" + this.placeholderSuffix + "', but found none.");
                }
            }
        } else {
            return string;
        }
    }

    int findPlaceholderStartIndex(String string) {
        int index = string.indexOf(this.placeholderPrefix);
        return (index != -1 ? index + this.placeholderPrefix.length() : index);
    }
    
    boolean isNested(String string, int startIndex) {
        int prefixIndex = string.indexOf(this.placeholderPrefix, startIndex);
        if (prefixIndex != -1) {
            int suffixIndex = string.indexOf(this.placeholderSuffix);
            return (prefixIndex < suffixIndex);
        } else {
            return false;
        }
    }
    
    int findPlaceholderEndIndex(String string, int startIndex) {
        return string.indexOf(this.placeholderSuffix, startIndex);
    }
    
    String replace(String string, int placeholderStartIndex, int placeholderEndIndex, String value) {
        StringBuffer buffer = new StringBuffer();
        buffer.append(string);
        buffer.replace(placeholderStartIndex - this.placeholderPrefix.length(), placeholderEndIndex + 1, value);
        return buffer.toString();
    }
}